package com.wskeee.ec.components
{
	import com.wskeee.ec.components.skin.ImageSkin;
	import com.wskeee.ec.containers.LayoutConst;
	import com.wskeee.ec.core.SkinableComponent;
	import com.wskeee.ec.logger.Logger;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.IBitmapDrawable;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	
	public class Image extends SkinableComponent
	{
		public function Image()
		{
			super();
			setActualSize(18,18);
			SkinDrawer = ImageSkin;
		}
		//--------------------------------------------------------------------------
		//
		//  variables
		//
		//--------------------------------------------------------------------------
		//-----------------------------------------------------------------
		//  get & set variables
		//-----------------------------------------------------------------
		private var _source:Object;
		private var _bitmapData:BitmapData;
		private var _bytesLoaded:Number;
		private var _bytesTotal:Number;
		private var _sourceWidth:Number;
		private var _sourceHeight:Number;
		private var _horizontalAlign:String = LayoutConst.CENTER;
		private var _verticalAlign:String = LayoutConst.MIDDLE;
		private var _scale:Boolean = false;
		private var _enableLoadingState:Boolean = true;
		
		//-----------------------------------------------------------------
		//  style variables
		//-----------------------------------------------------------------
		private var _backgroundAlpha:Number=0;
		private var _backgroundColor:uint = 0xFFFFFF;
		
		//-----------------------------------------------------------------
		//  private variables
		//-----------------------------------------------------------------
		private var sourceChangedFlag:Boolean = false;
		/**
		 *  用于加载外部资源
		 */
		private var loader:Loader;
		/**
		 * 源内容，主要用于重画
		 * source = String 时 sourceContent 为Loader加载后Loader.content;
		 * source = BitmapData/DisplayObject 时sourceContent为source引用
		 * source = class 时sourceContent 为 new Class（） instance 实例 
		 */
		private var sourceContent:Object;
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		//-----------------------------------------------------------------
		//  style
		//-----------------------------------------------------------------

		/**
		 *背景颜色 
		 */
		public function get backgroundColor():uint
		{
			return _backgroundColor;
		}

		/**
		 * @private
		 */
		public function set backgroundColor(value:uint):void
		{
			_backgroundColor = value;
			invalidateProperties();
		}

		/**
		 * 背景透明度 
		 */
		public function get backgroundAlpha():Number
		{
			return _backgroundAlpha;
		}

		/**
		 * @private
		 */
		public function set backgroundAlpha(value:Number):void
		{
			_backgroundAlpha = value;
			invalidateProperties();
		}

		//-----------------------------------------------------------------
		//  public properties
		//-----------------------------------------------------------------
		/**
		 * 启用加载状态进度显示 
		 */
		public function get enableLoadingState():Boolean
		{
			return _enableLoadingState;
		}
		
		/**
		 * @private
		 */
		public function set enableLoadingState(value:Boolean):void
		{
			_enableLoadingState = value;
			invalidateProperties();
			invalidateDisplayList();
		}
		/**
		 * 图片缩放 
		 */
		public function get scale():Boolean
		{
			return _scale;
		}

		/**
		 * @private
		 */
		public function set scale(value:Boolean):void
		{
			_scale = value;
			invalidateProperties();
			invalidateDisplayList();
		}

		/**
		 * 图片垂直对齐方式 
		 */
		public function get verticalAlign():String
		{
			return _verticalAlign;
		}

		/**
		 * @private
		 */
		public function set verticalAlign(value:String):void
		{
			_verticalAlign = value;
			invalidateProperties();
			invalidateDisplayList();
		}

		/**
		 * 图片水平对齐方式 
		 */
		public function get horizontalAlign():String
		{
			return _horizontalAlign;
		}

		/**
		 * @private
		 */
		public function set horizontalAlign(value:String):void
		{
			_horizontalAlign = value;
			invalidateProperties();
			invalidateDisplayList();
		}

		/**
		 * 数据源高 
		 */
		public function get sourceHeight():Number
		{
			return _sourceHeight;
		}

		/**
		 * 数据源宽 
		 */
		public function get sourceWidth():Number
		{
			return _sourceWidth;
		}

		/**
		 * 总共字节数  bit
		 */
		public function get bytesTotal():Number
		{
			return _bytesTotal;
		}

		/**
		 * 已加载字节数 bit
		 */
		public function get bytesLoaded():Number
		{
			return _bytesLoaded;
		}

		/**
		 * 源数据 
		 */
		public function get bitmapData():BitmapData
		{
			return _bitmapData;
		}

		/**
		 * 数据源
		 * 支持格式有：
		 * String 图片路径 
		 * BitmapData 
		 * DisplayObject
		 * Class
		 */
		public function get source():Object
		{
			return _source;
		}

		/**
		 * @private
		 */
		public function set source(value:Object):void
		{
			if(_source!=value)
			{
				_source = value;
				sourceChangedFlag = true;
				invalidateProperties();
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Method
		//
		//--------------------------------------------------------------------------
		//-----------------------------------------------------------------
		//  initChldren
		//-----------------------------------------------------------------
		override protected function initChildren():void
		{
			super.initChildren();
			initLoader();
		}
		
		//-----------------------------------------------------------------
		//  commitProperties
		//-----------------------------------------------------------------
		override protected function commitProperties():void
		{
			super.commitProperties();
			if(sourceChangedFlag)
			{
				sourceChangedFlag = false;
				checkSource(source);;
			}
		}
		
		override protected function measure():void
		{
			super.measure();
			if(isNaN(explicitWidth) || isNaN(explicitHeight))
			{
				if(!isNaN(sourceWidth) && !isNaN(sourceHeight))
					setActualSize(sourceWidth+1,sourceHeight+1);
			}
		}
		//-----------------------------------------------------------------
		//  loader
		//-----------------------------------------------------------------
		private function initLoader():void
		{
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaderComleteHandler);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onLoaderIOErrorHandler);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onLoaderProgressHandler);
		}
		
		private function onLoaderProgressHandler(event:ProgressEvent):void
		{
			_bytesLoaded = event.bytesLoaded;
			_bytesTotal = event.bytesLoaded;
			dispatchEvent(event);
		}
		
		private function onLoaderIOErrorHandler(event:IOErrorEvent):void
		{
			dispatchEvent(event);
		}
		
		private function onLoaderComleteHandler(event:Event):void
		{
			checkSource(loader.content);
		}
		
		private function destoryLoader():void
		{
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaderComleteHandler);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onLoaderIOErrorHandler);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onLoaderProgressHandler);
			loader.unload();
			loader = null;
		}
		
		/**
		 * 使用Loader加载内容 
		 * @param value	外部内容路径
		 * 
		 */
		protected function loadContent(value:String):void
		{
			try
			{
				loader.unload();
			} 
			catch(error:Error) {}
			loader.load(new URLRequest(value));
		}
		//--------------------------------------------------------------------------
		//
		//  protected Method
		//
		//--------------------------------------------------------------------------
		/**
		 * 设置 重画对象源 
		 * @param value
		 * 
		 */
		protected function setContent(value:Object):void
		{
			sourceContent = value;
			_sourceWidth = sourceContent.width;
			_sourceHeight = sourceContent.height;
			if(value is BitmapData)
			{
				_bitmapData = value as BitmapData;
			}else
			{
				try
				{
					var m:Matrix = new Matrix(1,0,0,1,0.5,0.5);
					_bitmapData = new BitmapData(sourceWidth+1,sourceHeight+1,true,0);
					_bitmapData.draw(sourceContent as IBitmapDrawable,m,null,null,null,true);
				} 
				catch(error:Error) 
				{
					Logger.error("获取 sourceWidth/sourceHeight出错: "+error.message);
				}
			}
			invalidateSize();
			dispatchEvent(new Event(Event.COMPLETE));
			if(isNaN(explicitWidth) || isNaN(explicitHeight))
				dispatchEvent(new Event(Event.RESIZE));
		}
		
		/**
		 * 检查数据源，选择一种显示方式 
		 * @param value
		 * 
		 */
		protected function checkSource(value:Object):void
		{
			if(value is String)
			{
				loadContent(value as String);
			}else if(value is BitmapData)
			{
				setContent(value);	
			}else if(value is Bitmap)
			{
				setContent(Bitmap(value).bitmapData);
			}else if(value is DisplayObject)
			{
				setContent(value);
			}else if(value is Class)
			{
				var CC:Class = value as Class;
				setContent(new CC());
			}
		}
	}
}